package cn.sc.summer.auth.util;

import cn.hutool.core.util.StrUtil;
import cn.sc.summer.constant.token.TokenConstant;
import cn.sc.summer.redis.util.RedisHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.NonNull;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * 类名：验证码校验工具类
 *
 * @author a-xin
 * @date 2023/11/28 13:30
 */
@Slf4j
@Component
public class ValidateCodeUtil {

    public static final String SMS_CODE = "smsCode";
    public static final String SMS_RANDOM_KEY = "smsRandomKey";
    public static final String IMAGE_CODE = "imageCode";
    public static final String IMAGE_RANDOM_KEY = "imageRandomKey";

    private ValidateCodeUtil() {
    }

    /**
     * 校验图形验证码，code：验证码，randomKey：校验唯一key
     *
     * @param request 请求体
     */
    public static void checkImageCode(@NonNull HttpServletRequest request) {
        checkImageCode(request.getRequestURI(), request.getHeader(IMAGE_CODE), request.getHeader(IMAGE_RANDOM_KEY));
    }

    /**
     * 校验图形验证码，code：验证码，randomKey：校验唯一key
     */
    public static void checkImageCode(@NonNull String path, @NonNull String imageCode, @NonNull String imageRandomKey) {

        if (StrUtil.isBlank(imageCode) || StrUtil.isBlank(imageRandomKey)) {
            log.error("==> The path [{}] , The graphic captcha cannot be empty！", path);
            throw new AuthenticationServiceException("The graphic captcha cannot be empty！");
        }

        if (!RedisHelper.hasKey(TokenConstant.CODE_KEY + imageRandomKey)) {
            log.error("==> The path [{}] , The graphic captcha has expired, please update！", path);
            throw new AuthenticationServiceException("The graphic captcha has expired, please update！");
        }

        String redisCode = (String) RedisHelper.get(TokenConstant.CODE_KEY + imageRandomKey);
        if (StrUtil.isBlank(redisCode)) {
            RedisHelper.del(TokenConstant.CODE_KEY + imageRandomKey);
            log.error("==> The path [{}] , The graphic captcha has expired, please update！", path);
            throw new AuthenticationServiceException("The graphic captcha has expired, please update！");
        }

        if (!imageCode.equals(redisCode)) {
            RedisHelper.del(TokenConstant.CODE_KEY + imageRandomKey);
            log.error("==> The path [{}] , Graphics captcha error！", path);
            throw new AuthenticationServiceException("Graphics captcha error！");
        }

        RedisHelper.del(TokenConstant.CODE_KEY + imageRandomKey);

    }

    /**
     * 校验短信验证码，code：验证码，randomKey：校验唯一key
     *
     * @param request 请求体
     */
    public static void checkSmsCode(@NonNull HttpServletRequest request) {
        checkSmsCode(request.getRequestURI(), request.getHeader(SMS_CODE), request.getHeader(SMS_RANDOM_KEY));
    }

    /**
     * 校验短信验证码，code：验证码，randomKey：校验唯一key
     */
    public static void checkSmsCode(@NonNull String path, @NonNull String smsCode, @NonNull String smsRandomKey) {

        if (StrUtil.isBlank(smsCode) || StrUtil.isBlank(smsRandomKey)) {
            log.error("==> The path [{}] , The smsCode cannot be empty！", path);
            throw new AuthenticationServiceException("The smsCode cannot be empty！");
        }

        if (!RedisHelper.hasKey(TokenConstant.SMS_CODE_KEY + smsRandomKey)) {
            log.error("==> The path [{}] , The smsCode has expired, please update！", path);
            throw new AuthenticationServiceException("The smsCode has expired, please update！");
        }

        String redisCode = (String) RedisHelper.get(TokenConstant.SMS_CODE_KEY + smsRandomKey);
        if (StrUtil.isBlank(redisCode)) {
            RedisHelper.del(TokenConstant.SMS_CODE_KEY + smsRandomKey);
            log.error("==> The path [{}] , The smsCode has expired, please update！", path);
            throw new AuthenticationServiceException("The smsCode has expired, please update！");
        }

        if (!smsCode.equals(redisCode)) {
            RedisHelper.del(TokenConstant.SMS_CODE_KEY + smsRandomKey);
            log.error("==> The path [{}] , SmsCode error！", path);
            throw new AuthenticationServiceException("SmsCode error！");
        }

        RedisHelper.del(TokenConstant.SMS_CODE_KEY + smsRandomKey);

    }

}
